<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>9. Errores y excepciones &mdash; Tutorial de Python v2.6.2 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '#',
        VERSION:     '2.6.2',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Tutorial de Python v2.6.2 documentation" href="index.html" />
    <link rel="next" title="10. Clases" href="classes.html" />
    <link rel="prev" title="8. Entrada y salida" href="inputoutput.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navegación</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="Índice General"
             accesskey="I">índice</a></li>
        <li class="right" >
          <a href="classes.html" title="10. Clases"
             accesskey="N">siguiente</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="8. Entrada y salida"
             accesskey="P">anterior</a> |</li>
        <li><a href="contenido.html">Tutorial de Python v2.6.2 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="errores-y-excepciones">
<span id="tut-errors"></span><h1>9. Errores y excepciones<a class="headerlink" href="#errores-y-excepciones" title="Enlazar permanentemente con este título">¶</a></h1>
<p>Hasta ahora los mensajes de error no habían sido más que mencionados, pero si
probaste los ejemplos probablemente hayas visto algunos.  Hay (al menos) dos
tipos diferentes de errores: <em>errores de sintaxis</em> y <em>excepciones</em>.</p>
<div class="section" id="errores-de-sintaxis">
<span id="tut-syntaxerrors"></span><h2>9.1. Errores de sintaxis<a class="headerlink" href="#errores-de-sintaxis" title="Enlazar permanentemente con este título">¶</a></h2>
<p>Los errores de sintaxis, también conocidos como errores de interpretación, son
quizás el tipo de queja más común que tenés cuando todavía estás aprendiendo
Python:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">while</span> <span class="bp">True</span> <span class="k">print</span> <span class="s">&#39;Hola mundo&#39;</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="c">...</span>
    <span class="k">while</span> <span class="bp">True</span> <span class="k">print</span> <span class="s">&#39;Hola mundo&#39;</span>
                   <span class="o">^</span>
<span class="nc">SyntaxError</span>: <span class="n-Identifier">invalid syntax</span>
</pre></div>
</div>
<p>El intérprete repite la línea culpable y muestra una pequeña &#8216;flecha&#8217;
que apunta al primer lugar donde se detectó el error.  Este es causado por (o
al menos detectado en) el símbolo que <em>precede</em> a la flecha: en el ejemplo,
el error se detecta en el <tt class="xref docutils literal"><span class="pre">print</span></tt>, ya que faltan dos puntos (<tt class="docutils literal"><span class="pre">':'</span></tt>)
antes del mismo.  Se muestran el nombre del archivo y el número de línea para
que sepas dónde mirar en caso de que la entrada venga de un programa.</p>
</div>
<div class="section" id="excepciones">
<span id="tut-exceptions"></span><h2>9.2. Excepciones<a class="headerlink" href="#excepciones" title="Enlazar permanentemente con este título">¶</a></h2>
<p>Incluso si la declaración o expresión es sintácticamente correcta, puede
generar un error cuando se intenta ejecutarla.  Los errores detectados durante
la ejecución se llaman <em>excepciones</em>, y no son incondicionalmente fatales:
pronto aprenderás cómo manejarlos en los programas en Python.  Sin embargo, la
mayoría de las excepciones no son manejadas por los programas, y resultan en
mensajes de error como los mostrados aquí:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="mi">10</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
<span class="nc">ZeroDivisionError</span>: <span class="n-Identifier">integer division or modulo by zero</span>
<span class="gp">&gt;&gt;&gt; </span><span class="mi">4</span> <span class="o">+</span> <span class="n">spam</span><span class="o">*</span><span class="mi">3</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
<span class="nc">NameError</span>: <span class="n-Identifier">name &#39;spam&#39; is not defined</span>
<span class="gp">&gt;&gt;&gt; </span><span class="s">&#39;2&#39;</span> <span class="o">+</span> <span class="mi">2</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
<span class="nc">TypeError</span>: <span class="n-Identifier">cannot concatenate &#39;str&#39; and &#39;int&#39; objects</span>
</pre></div>
</div>
<p>La última línea de los mensajes de error indica qué sucedió.  Las excepciones
vienen de distintos tipos, y el tipo se imprime como parte del mensaje: los
tipos en el ejemplo son: <tt class="xref docutils literal"><span class="pre">ZeroDivisionError</span></tt>, <tt class="xref docutils literal"><span class="pre">NameError</span></tt> y
<tt class="xref docutils literal"><span class="pre">TypeError</span></tt>.  La cadena mostrada como tipo de la excepción es el nombre de
la excepción predefinida que ocurrió.  Esto es verdad para todas las
excepciones predefinidas del intérprete, pero no necesita ser verdad para
excepciones definidas por el usuario (aunque es una convención útil).  Los
nombres de las excepciones estándar son identificadores incorporados al
intérprete (no son palabras clave reservadas).</p>
<p>El resto de la línea provee un detalle basado en el tipo de la excepción y qué
la causó.</p>
<p>La parte anterior del mensaje de error muestra el contexto donde la excepción
sucedió, en la forma de un <em>trazado del error</em> listando líneas fuente; sin
embargo, no mostrará líneas leídas desde la entrada estándar.</p>
<p><em class="xref">bltin-exceptions</em> lista las excepciones predefinidas y sus significados.</p>
</div>
<div class="section" id="manejando-excepciones">
<span id="tut-handling"></span><h2>9.3. Manejando excepciones<a class="headerlink" href="#manejando-excepciones" title="Enlazar permanentemente con este título">¶</a></h2>
<p>Es posible escribir programas que manejen determinadas excepciones.  Mirá el
siguiente ejemplo, que le pide al usuario una entrada hasta que ingrese un
entero válido, pero permite al usuario interrumpir el programa (usando
<tt class="docutils literal"><span class="pre">Control-C</span></tt> o lo que sea que el sistema operativo soporte); notá que una
interrupción generada por el usuario se señaliza generando la excepción
<tt class="xref docutils literal"><span class="pre">KeyboardInterrupt</span></tt>.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">x</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">raw_input</span><span class="p">(</span><span class="s">u&quot;Por favor ingrese un número: &quot;</span><span class="p">))</span>
<span class="gp">... </span>        <span class="k">break</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">print</span> <span class="s">u&quot;Oops!  No era válido.  Intente nuevamente...&quot;</span>
<span class="gp">...</span>
</pre></div>
</div>
<p>La declaración <tt class="xref docutils literal"><span class="pre">try</span></tt> funciona de la siguiente manera:</p>
<ul class="simple">
<li>Primero, se ejecuta el <em>bloque try</em> (el código entre las declaración
<tt class="xref docutils literal"><span class="pre">try</span></tt> y <tt class="xref docutils literal"><span class="pre">except</span></tt>).</li>
<li>Si no ocurre ninguna excepción, el <em>bloque except</em> se saltea y termina la
ejecución de la declaración <tt class="xref docutils literal"><span class="pre">try</span></tt>.</li>
<li>Si ocurre una excepción durante la ejecución del <em>bloque try</em>, el resto del
bloque se saltea.  Luego, si su tipo coincide con la excepción nombrada luego
de la palabra reservada <tt class="xref docutils literal"><span class="pre">except</span></tt>, se ejecuta el <em>bloque except</em>,
y la ejecución continúa luego de la declaración <tt class="xref docutils literal"><span class="pre">try</span></tt>.</li>
<li>Si ocurre una excepción que no coincide con la excepción nombrada en el
<tt class="xref docutils literal"><span class="pre">except</span></tt>, esta se pasa a declaraciones <tt class="xref docutils literal"><span class="pre">try</span></tt> de más afuera;
si no se encuentra nada que la maneje, es una <em>excepción no manejada</em>, y la
ejecución se frena con un mensaje como los mostrados arriba.</li>
</ul>
<p>Una declaración <tt class="xref docutils literal"><span class="pre">try</span></tt> puede tener más de un <tt class="xref docutils literal"><span class="pre">except</span></tt>, para
especificar manejadores para distintas excepciones.  A lo sumo un manejador
será ejecutado.  Sólo se manejan excepciones que ocurren en el correspondiente
<tt class="xref docutils literal"><span class="pre">try</span></tt>, no en otros manejadores del mismo <tt class="xref docutils literal"><span class="pre">try</span></tt>.  Un
<tt class="xref docutils literal"><span class="pre">except</span></tt> puede nombrar múltiples excepciones usando paréntesis, por
ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="o">...</span> <span class="k">except</span> <span class="p">(</span><span class="ne">RuntimeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="ne">NameError</span><span class="p">):</span>
<span class="o">...</span>     <span class="k">pass</span>
</pre></div>
</div>
<p>El último <tt class="xref docutils literal"><span class="pre">except</span></tt> puede omitir nombrar qué excepción captura, para
servir como comodín.  Usá esto con extremo cuidado, ya que de esta manera es
fácil ocultar un error real de programación.  También puede usarse para mostrar
un mensaje de error y luego re-generar la excepción (permitiéndole al que
llama, manejar también la excepción):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span>

<span class="k">try</span><span class="p">:</span>
    <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&#39;miarchivo.txt&#39;</span><span class="p">)</span>
    <span class="n">s</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
    <span class="n">i</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">IOError</span> <span class="k">as</span> <span class="p">(</span><span class="n">errno</span><span class="p">,</span> <span class="n">strerror</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&quot;Error E/S ({0}): {1}&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">errno</span><span class="p">,</span> <span class="n">strerror</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;No pude convertir el dato a un entero.&quot;</span>
<span class="k">except</span><span class="p">:</span>
    <span class="k">print</span> <span class="s">&quot;Error inesperado:&quot;</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
    <span class="k">raise</span>
</pre></div>
</div>
<p>Las declaraciones <tt class="xref docutils literal"><span class="pre">try</span></tt> ... <tt class="xref docutils literal"><span class="pre">except</span></tt> tienen un <em>bloque else</em>
opcional, el cual, cuando está presente, debe seguir a los except.  Es útil
para aquel código que debe ejecutarse si el <em>bloque try</em> no genera una
excepción.  Por ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&#39;no pude abrir&#39;</span><span class="p">,</span> <span class="n">arg</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">arg</span><span class="p">,</span> <span class="s">&#39;tiene&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()),</span> <span class="s">&#39;lineas&#39;</span>
        <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>El uso de <tt class="xref docutils literal"><span class="pre">else</span></tt> es mejor que agregar código adicional en el
<tt class="xref docutils literal"><span class="pre">try</span></tt> porque evita capturar accidentalmente una excepción que no fue
generada por el código que está protegido por la declaración <tt class="xref docutils literal"><span class="pre">try</span></tt> ...
<tt class="xref docutils literal"><span class="pre">except</span></tt>.</p>
<p>Cuando ocurre una excepción, puede tener un valor asociado, también conocido
como el <em>argumento</em> de la excepción.  La presencia y el tipo de argumento
depende del tipo de excepción.</p>
<p>El <tt class="xref docutils literal"><span class="pre">except</span></tt> puede especificar una variable luego del nombre (o tupla)
de excepción(es).  La variable se vincula a una instancia de excepción con los
argumentos almacenados en <tt class="docutils literal"><span class="pre">instance.args</span></tt>.  Por conveniencia, la instancia
de excepción define <tt class="xref docutils literal"><span class="pre">__getitem__()</span></tt> y <tt class="xref docutils literal"><span class="pre">__str__()</span></tt> para que se pueda
acceder o mostrar los argumentos directamente, sin necesidad de hacer
referencia a <tt class="docutils literal"><span class="pre">.args</span></tt>.</p>
<p>Pero se recomienda no usar <tt class="docutils literal"><span class="pre">.args</span></tt>.  En cambio, el uso preferido es pasar un
único argumento a la excepción (que puede ser una tupla se necesitan varios
argumentos) y vincularlo al atributo <tt class="docutils literal"><span class="pre">message</span></tt>.  Uno también puede instanciar
una excepción antes de generarla, y agregarle cualquier atributo que se
desee:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>   <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">&#39;carne&#39;</span><span class="p">,</span> <span class="s">&#39;huevos&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">inst</span><span class="p">:</span>
<span class="gp">... </span>   <span class="k">print</span> <span class="nb">type</span><span class="p">(</span><span class="n">inst</span><span class="p">)</span>     <span class="c"># la instancia de excepción</span>
<span class="gp">... </span>   <span class="k">print</span> <span class="n">inst</span><span class="o">.</span><span class="n">args</span>      <span class="c"># argumentos guardados en .args</span>
<span class="gp">... </span>   <span class="k">print</span> <span class="n">inst</span>           <span class="c"># __str__ permite imprimir args directamente</span>
<span class="gp">... </span>   <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">inst</span>          <span class="c"># __getitem__ permite usar args directamente</span>
<span class="gp">... </span>   <span class="k">print</span> <span class="s">&#39;x =&#39;</span><span class="p">,</span> <span class="n">x</span>
<span class="gp">... </span>   <span class="k">print</span> <span class="s">&#39;y =&#39;</span><span class="p">,</span> <span class="n">y</span>
<span class="gp">...</span>
<span class="go">&lt;type &#39;exceptions.Exception&#39;&gt;</span>
<span class="go">(&#39;carne&#39;, &#39;huevos&#39;)</span>
<span class="go">(&#39;carne&#39;, &#39;huevos&#39;)</span>
<span class="go">x = carne</span>
<span class="go">y = huevos</span>
</pre></div>
</div>
<p>Si una excepción tiene un argumento, este se imprime como la última parte (el
&#8216;detalle&#8217;) del mensaje para las excepciones que no están manejadas.</p>
<p>Los manejadores de excepciones no manejan solamente las excepciones que
ocurren en el <em>bloque try</em>, también manejan las excepciones que ocurren
dentro de las funciones que se llaman (inclusive indirectamente) dentro del
<em>bloque try</em>.  Por ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">esto_falla</span><span class="p">():</span>
<span class="gp">... </span>    <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">esto_falla</span><span class="p">()</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">ZeroDivisionError</span> <span class="k">as</span> <span class="n">detail</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">&#39;Manejando error en tiempo de ejecucion:&#39;</span><span class="p">,</span> <span class="n">detail</span>
<span class="gp">...</span>
<span class="go">Manejando error en tiempo de ejecucion: integer division or modulo by zero</span>
</pre></div>
</div>
</div>
<div class="section" id="levantando-excepciones">
<span id="tut-raising"></span><h2>9.4. Levantando excepciones<a class="headerlink" href="#levantando-excepciones" title="Enlazar permanentemente con este título">¶</a></h2>
<p>La declaración <tt class="xref docutils literal"><span class="pre">raise</span></tt> permite al programador forzar a que ocurra
una excepción específica.  Por ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s">&#39;Hola&#39;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
<span class="nc">NameError</span>: <span class="n-Identifier">Hola</span>
</pre></div>
</div>
<p>El argumento de <tt class="xref docutils literal"><span class="pre">raise</span></tt> es una clase o instancia de excepción a ser
generada.  Hay una sintaxis alternativa que no se usa más, que separa los
argumentos de clase y constructor; lo de arriba podría escribirse como
<tt class="docutils literal"><span class="pre">raise</span> <span class="pre">NameError,</span> <span class="pre">'Hola'</span></tt>; ya que alguna vez era la única opción, esta forma
es muy usada en códigos viejos.</p>
<p>Si necesitás determinar cuando una excepción fue lanzada pero no querés
manejarla, una forma simplificada de la instrucción <tt class="xref docutils literal"><span class="pre">raise</span></tt> te permite
relanzarla:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s">&#39;Hola&#39;</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">u&#39;Voló una excepción!&#39;</span>
<span class="gp">... </span>    <span class="k">raise</span>
<span class="gp">...</span>
<span class="go">Voló una excpeción!</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">2</span>, in <span class="n-Identifier">?</span>
<span class="nc">NameError</span>: <span class="n-Identifier">Hola</span>
</pre></div>
</div>
</div>
<div class="section" id="excepciones-definidas-por-el-usuario">
<span id="tut-userexceptions"></span><h2>9.5. Excepciones definidas por el usuario<a class="headerlink" href="#excepciones-definidas-por-el-usuario" title="Enlazar permanentemente con este título">¶</a></h2>
<p>Los programas pueden nombrar sus propias excepciones creando una nueva clase
excepción.  Las excepciones, típicamente, deberán derivar de la clase
<tt class="xref docutils literal"><span class="pre">Exception</span></tt>, directa o indirectamente.  Por ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">MiError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">valor</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">valor</span> <span class="o">=</span> <span class="n">valor</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">valor</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="n">MiError</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">MyError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">u&#39;Ocurrió mi excepción, valor:&#39;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">valor</span>
<span class="gp">...</span>
<span class="go">Ocurrió mi excepción, valor: 4</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">raise</span> <span class="n">MiError</span><span class="p">(</span><span class="s">&#39;oops!&#39;</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
<span class="nc">__main__.MiError</span>: <span class="n-Identifier">&#39;oops!&#39;</span>
</pre></div>
</div>
<p>En este ejemplo, el método <tt class="xref docutils literal"><span class="pre">__init__()</span></tt> de <tt class="xref docutils literal"><span class="pre">Exception</span></tt> fue
sobrescrito.  El nuevo comportamiento simplemente crea el atributo <em>valor</em>.
Esto reemplaza el comportamiento por defecto de crear el atributo <em>args</em>.</p>
<p>Las clases de Excepciones pueden ser definidas de la misma forma que cualquier
otra clase, pero usualmente se mantienen simples, a menudo solo ofreciendo un
número de atributos con información sobre el error que leerán los manejadores
de la excepción.  Al crear un módulo que puede lanzar varios errores distintos,
una práctica común es crear una clase base para excepciones definidas en ese
módulo y extenderla para crear clases excepciones específicas para distintas
condiciones de error:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Error</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Clase base para excepciones en el modulo.&quot;&quot;&quot;</span>
    <span class="k">pass</span>

<span class="k">class</span> <span class="nc">EntradaError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Excepcion lanzada por errores en las entradas.</span>

<span class="sd">    Atributos:</span>
<span class="sd">        expresion -- expresion de entrada en la que ocurre el error</span>
<span class="sd">        mensaje -- explicacion del error</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expresion</span><span class="p">,</span> <span class="n">mensaje</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">expresion</span> <span class="o">=</span> <span class="n">expresion</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">mensaje</span> <span class="o">=</span> <span class="n">mensaje</span>

<span class="k">class</span> <span class="nc">TransicionError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Lanzada cuando una operacion intenta una transicion de estado no</span>
<span class="sd">    permitida.</span>

<span class="sd">    Atributos:</span>
<span class="sd">        previo -- estado al principio de la transicion</span>
<span class="sd">        siguiente -- nuevo estado intentado</span>
<span class="sd">        mensaje -- explicacion de porque la transicion no esta permitida</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">previo</span><span class="p">,</span> <span class="n">siguiente</span><span class="p">,</span> <span class="n">mensaje</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">previo</span> <span class="o">=</span> <span class="n">previo</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">siguiente</span> <span class="o">=</span> <span class="n">siguiente</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">mensaje</span> <span class="o">=</span> <span class="n">mensaje</span>
</pre></div>
</div>
<p>La mayoría de las excepciones son definidas con nombres que terminan en
&#8220;Error&#8221;, similares a los nombres de las excepciones estándar.</p>
<p>Muchos módulos estándar definen sus propias excepciones para reportar errores
que pueden ocurrir en funciones propias. Se puede encontrar más información
sobre clases en el capítulo <a class="reference external" href="classes.html#tut-classes"><em>Clases</em></a>.</p>
</div>
<div class="section" id="definiendo-acciones-de-limpieza">
<span id="tut-cleanup"></span><h2>9.6. Definiendo acciones de limpieza<a class="headerlink" href="#definiendo-acciones-de-limpieza" title="Enlazar permanentemente con este título">¶</a></h2>
<p>La declaración <tt class="xref docutils literal"><span class="pre">try</span></tt> tiene otra cláusula opcional que intenta
definir acciones de limpieza que deben ser ejecutadas bajo ciertas
circunstancias. Por ejemplo:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">raise</span> <span class="ne">KeyboardInterrupt</span>
<span class="gp">... </span><span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">&#39;Chau, mundo!&#39;</span>
<span class="gp">...</span>
<span class="go">Chau, mundo!</span>
<span class="nc">KeyboardInterrupt</span>
</pre></div>
</div>
<p>Una <em>cláusula finally</em> siempre es ejecutada antes de salir de la declaración
<tt class="xref docutils literal"><span class="pre">try</span></tt>, ya sea que una excepción haya ocurrido o no.  Cuando ocurre una
excepción en la cláusula <tt class="xref docutils literal"><span class="pre">try</span></tt> y no fue manejada por una cláusula
<tt class="xref docutils literal"><span class="pre">except</span></tt> (o ocurrió en una cláusula <tt class="xref docutils literal"><span class="pre">except</span></tt> o
<tt class="xref docutils literal"><span class="pre">else</span></tt>), es relanzada luego de que se ejecuta la cláusula
<tt class="xref docutils literal"><span class="pre">finally</span></tt>. <tt class="xref docutils literal"><span class="pre">finally</span></tt> es también ejecutada &#8220;a la salida&#8221;
cuando cualquier otra cláusula de la declaración <tt class="xref docutils literal"><span class="pre">try</span></tt> es dejada
via <tt class="xref docutils literal"><span class="pre">break</span></tt>, <tt class="xref docutils literal"><span class="pre">continue</span></tt> or <tt class="xref docutils literal"><span class="pre">return</span></tt>.  Un ejemplo
más complicado (cláusulas <tt class="xref docutils literal"><span class="pre">except</span></tt> y <tt class="xref docutils literal"><span class="pre">finally</span></tt> en la misma
declaración <tt class="xref docutils literal"><span class="pre">try</span></tt>):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">dividir</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="n">result</span> <span class="o">=</span> <span class="n">x</span> <span class="o">/</span> <span class="n">y</span>
<span class="gp">... </span>    <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">print</span> <span class="s">&quot;¡division por cero!&quot;</span>
<span class="gp">... </span>    <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">print</span> <span class="s">&quot;el resultado es&quot;</span><span class="p">,</span> <span class="n">result</span>
<span class="gp">... </span>    <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">print</span> <span class="s">&quot;ejecutando la clausula finally&quot;</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dividir</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">el resultado es 2</span>
<span class="go">ejecutando la clausula finally</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">dividir</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">¡division por cero!</span>
<span class="go">ejecutando la clausula finally</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">divide</span><span class="p">(</span><span class="s">&quot;2&quot;</span><span class="p">,</span> <span class="s">&quot;1&quot;</span><span class="p">)</span>
<span class="go">ejecutando la clausula finally</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n-Identifier">?</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">3</span>, in <span class="n-Identifier">divide</span>
<span class="nc">TypeError: unsupported operand type(s) for /</span>: <span class="n-Identifier">&#39;str&#39; and &#39;str&#39;</span>
</pre></div>
</div>
<p>Como podés ver, la cláusula <tt class="xref docutils literal"><span class="pre">finally</span></tt> es ejecutada siempre.  La
excepción <tt class="xref docutils literal"><span class="pre">TypeError</span></tt> lanzada al dividir dos cadenas de texto no es
manejado por la cláusula <tt class="xref docutils literal"><span class="pre">except</span></tt> y por lo tanto es relanzada luego
de que se ejecuta la cláusula <tt class="xref docutils literal"><span class="pre">finally</span></tt>.</p>
<p>En aplicaciones reales, la cláusula <tt class="xref docutils literal"><span class="pre">finally</span></tt> es útil para liberar
recursos externos (como archivos o conexiones de red), sin importar si el
uso del recurso fue exitoso.</p>
</div>
<div class="section" id="acciones-predefinidas-de-limpieza">
<span id="tut-cleanup-with"></span><h2>9.7. Acciones predefinidas de limpieza<a class="headerlink" href="#acciones-predefinidas-de-limpieza" title="Enlazar permanentemente con este título">¶</a></h2>
<p>Algunos objetos definen acciones de limpieza estándar que llevar a cabo cuando
el objeto no es más necesitado, independientemente de que las operaciones
sobre el objeto hayan sido exitosas o no.  Mirá el siguiente ejemplo, que
intenta abrir un archivo e imprimir su contenido en la pantalla.:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">for</span> <span class="n">linea</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;miarchivo.txt&quot;</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">linea</span>
</pre></div>
</div>
<p>El problema con este código es que deja el archivo abierto por un periodo de
tiempo indeterminado luego de que termine de ejecutarse.  Esto no es un
problema en scripts simples, pero puede ser un problema en aplicaciones más
grandes.  La declaración <tt class="xref docutils literal"><span class="pre">with</span></tt> permite que objetos como archivos sean
usados de una forma que asegure que siempre se los libera rápido y en forma
correcta.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;miarchivo.txt&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="k">for</span> <span class="n">linea</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
        <span class="k">print</span> <span class="n">linea</span>
</pre></div>
</div>
<p>Luego de que la declaración sea ejecutada, el archivo <em>f</em> siempre es cerrado,
incluso si se encuentra un problema al procesar las líneas.  Otros objetos que
provean acciones de limpieza predefinidas lo indicarán en su documentación.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="contenido.html">Contenidos</a></h3>
            <ul>
<li><a class="reference external" href="#">9. Errores y excepciones</a><ul>
<li><a class="reference external" href="#errores-de-sintaxis">9.1. Errores de sintaxis</a></li>
<li><a class="reference external" href="#excepciones">9.2. Excepciones</a></li>
<li><a class="reference external" href="#manejando-excepciones">9.3. Manejando excepciones</a></li>
<li><a class="reference external" href="#levantando-excepciones">9.4. Levantando excepciones</a></li>
<li><a class="reference external" href="#excepciones-definidas-por-el-usuario">9.5. Excepciones definidas por el usuario</a></li>
<li><a class="reference external" href="#definiendo-acciones-de-limpieza">9.6. Definiendo acciones de limpieza</a></li>
<li><a class="reference external" href="#acciones-predefinidas-de-limpieza">9.7. Acciones predefinidas de limpieza</a></li>
</ul>
</li>
</ul>

            <h4>Tema anterior</h4>
            <p class="topless"><a href="inputoutput.html"
                                  title="Capítulo anterior">8. Entrada y salida</a></p>
            <h4>Próximo tema</h4>
            <p class="topless"><a href="classes.html"
                                  title="Próximo capítulo">10. Clases</a></p>
            <h3>Esta página</h3>
            <ul class="this-page-menu">
              <li><a href="_sources/errors.txt"
                     rel="nofollow">Enseñar el código</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Búsqueda rápida</h3>
              <form class="search" action="search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Ir a" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Ingrese una palabra para buscar o un nombre de módulo, clase o función
              </p>
          </div>
          <h4><a href="/"> Volver a CdPedia </a></h4>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navegación</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="Índice General"
             >índice</a></li>
        <li class="right" >
          <a href="classes.html" title="10. Clases"
             >siguiente</a> |</li>
        <li class="right" >
          <a href="inputoutput.html" title="8. Entrada y salida"
             >anterior</a> |</li>
        <li><a href="contenido.html">Tutorial de Python v2.6.2 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright 2009, Python Software Foundation.
      Creado con <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.5.
    </div>
  </body>
</html>
